//-------------------------------------------------------------------
//	Copyright (c) 2010-2012  Zhirnov Andrey
//	This file is part of the "UXGEN" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#ifndef _UX_BASE_OBJECT_H
#define _UX_BASE_OBJECT_H

#include "AllTypes.h"

namespace Engine
{
	
	//
	// Thread Local Object
	//

	struct TThreadObject
	{
	public:
		THREAD_LOCAL static IThread				* _THREAD;
		THREAD_LOCAL static CCore				* _CORE;
		THREAD_LOCAL static IWindow				* _WINDOW;
		THREAD_LOCAL static ILogger				* _LOGGER;
		THREAD_LOCAL static CRender				* _RENDER;
		THREAD_LOCAL static CRenderSystem		* _RENDER_SYSTEM;
		//THREAD_LOCAL static CLDevice			* _CLDEVICE;
		THREAD_LOCAL static CInput				* _INPUT;
		THREAD_LOCAL static CFileSystem			* _FILESYS;
		THREAD_LOCAL static CResourceManager	* _RESMAN;
		THREAD_LOCAL static ALSoundSystem		* _SOUNDSYS;
		THREAD_LOCAL static UXParser::CConfig	* _CONFIG;
		//THREAD_LOCAL static CObjectManager		* _OBJMAN;
		THREAD_LOCAL static CGUISystem			* _GUISYS;
		THREAD_LOCAL static CGUIObjectFactory	* _GUIFACTORY;
		THREAD_LOCAL static CSceneObjectFactory	* _SOFACTORY;
		THREAD_LOCAL static TGLContext			* _pGLContext;
		THREAD_LOCAL static GLStateManager		* _SMAN;
		THREAD_LOCAL static GLObjectManager		* _GLOM;
		THREAD_LOCAL static GLBatchRender		* _BATCH;
		THREAD_LOCAL static GLMatrixStack		* _MSTACK;
		
	public:
		// call this function on enter thread only
		static void OnEnterThread(CCore *, IThread *);

		// call this function on exit thread only
		static void OnExitThread();
		
		static void	_s_SetSystems(CCore *, IWindow *, IThread *);
	};


	inline static Ptr< IThread >			THREAD()		{ return TThreadObject::_THREAD; }
	inline static Ptr< CCore >				CORE()			{ return TThreadObject::_CORE; }
	inline static Ptr< IWindow >			WINDOW()		{ return TThreadObject::_WINDOW; }
	inline static Ptr< ILogger >			LOGGER()		{ return TThreadObject::_LOGGER; }
	inline static Ptr< CRender >			RENDER()		{ return TThreadObject::_RENDER; }
	inline static Ptr< CRenderSystem >		RENDER_SYSTEM()	{ return TThreadObject::_RENDER_SYSTEM; }
	//inline static Ptr< CLDevice >			CLDEVICE()		{ return TThreadObject::_CLDEVICE; }
	inline static Ptr< CInput >				INPUT()			{ return TThreadObject::_INPUT; }
	inline static Ptr< CFileSystem >		FILESYS()		{ return TThreadObject::_FILESYS; }
	inline static Ptr< CResourceManager >	RESMAN()		{ return TThreadObject::_RESMAN; }
	inline static Ptr< ALSoundSystem >		SOUNDSYS()		{ return TThreadObject::_SOUNDSYS; }
	inline static Ptr< UXParser::CConfig >	CONFIG()		{ return TThreadObject::_CONFIG; }
	//inline static Ptr< CObjectManager >		OBJMAN()		{ return TThreadObject::_OBJMAN; }
	inline static Ptr< CGUISystem >			GUISYS()		{ return TThreadObject::_GUISYS; }
	inline static Ptr< CGUIObjectFactory >	GUIFACTORY()	{ return TThreadObject::_GUIFACTORY; }
	inline static Ptr< CSceneObjectFactory>	SOFACTORY()		{ return TThreadObject::_SOFACTORY; }
	inline static TGLContext const &		glGetContext()	{ return *TThreadObject::_pGLContext; }
	inline static Ptr< GLStateManager >		SMAN()			{ return TThreadObject::_SMAN; }
	inline static Ptr< GLObjectManager >	GLOM()			{ return TThreadObject::_GLOM; }
	inline static Ptr< GLBatchRender >		BATCH()			{ return TThreadObject::_BATCH; }
	inline static Ptr< GLMatrixStack >		MSTACK()		{ return TThreadObject::_MSTACK; }



	//
	// Engine Base Object
	//

	class _EXPORT_ CEngBaseObject
	{
	public:
		CEngBaseObject() {}
		virtual ~CEngBaseObject() {}

		virtual void Release()	{ delete this; }
	};


namespace GLShell { typedef CEngBaseObject		GLBaseObject; }
namespace ALShell { typedef CEngBaseObject		ALBaseObject; }
namespace CLShell { typedef CEngBaseObject		CLBaseObject; }
	
//-------------------------------------------------------------------

}	// Engine

#endif	// _UX_BASE_OBJECT_H